package com.tanhua.server.service;

import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.vo.CommentVo;
import com.tanhua.domain.vo.MomentVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 动态点赞，评论，喜欢功能模块
 */
@Service
public class CommentService {

    @Reference
    private CommentApi commentApi;

    @Autowired
    private RedisTemplate redisTemplate;

    @Reference
    private UserInfoApi userInfoApi;

    /**
     * 动态点赞
     *
     * @param publishId
     * @return
     */
    public long like(String publishId) {

        //1.获取登录用户id
        Long loginUserID = UserHolder.getUserId();

        //2.构建Comment对象
        Comment comment = new Comment();
        comment.setCommentType(1);//1：点赞
        comment.setTargetType(1);//1:动态
        comment.setTargetId(new ObjectId(publishId)); //动态id
        comment.setUserId(loginUserID);//点赞的人

        //3.调用api添加动态点赞
        long likeCount = commentApi.save(comment);

        //4.存入redis，标记当前登录用户对这个动态点赞了
        String key = "publish_like_" + loginUserID + "_" + publishId;

        //使用什么样的redis数据类型来替换key=value方式
        redisTemplate.opsForValue().set(key, 1);

        // 返回的点赞数
        return likeCount;
    }

    /**
     * 动态取消点赞
     *
     * @param publishId
     * @return
     */
    public long dislike(String publishId) {


        //获取登录用户id
        Long loginUserID = UserHolder.getUserId();
        //构建comment
        //2.构建Comment对象
        Comment comment = new Comment();
        comment.setCommentType(1);//1：点赞
        comment.setTargetId(new ObjectId(publishId)); //动态id
        comment.setUserId(loginUserID);//点赞的人
        comment.setTargetType(1); //1 对动态的操作, 这个条件可以省略 targetId就是唯一

        long likeCount = commentApi.remove(comment);

        String key = "publish_like_" + loginUserID + "_" + publishId;
        // 删除redis对点赞的标记
        redisTemplate.delete(key);
        return likeCount;
    }

    /**
     * 动态喜欢
     *
     * @param publishId
     * @return
     */
    public long love(String publishId) {

        //1.获取登录用户id
        Long loginUserID = UserHolder.getUserId();

        //2.构建Comment对象
        Comment comment = new Comment();
        comment.setCommentType(3);//1：点赞
        comment.setTargetType(1);//1:动态
        comment.setTargetId(new ObjectId(publishId)); //动态id
        comment.setUserId(loginUserID);//点赞的人

        //3.调用api添加动态点赞
        long loveCount = commentApi.save(comment);

        //4.存入redis，标记当前登录用户对这个动态喜欢了
        String key = "publish_love_" + loginUserID + "_" + publishId;

        //使用什么样的redis数据类型来替换key=value方式
        redisTemplate.opsForValue().set(key, 1);

        // 返回的点赞数
        return loveCount;
    }

    /**
     * 动态取消喜欢
     *
     * @param publishId
     * @return
     */
    public long unlove(String publishId) {
        //获取登录用户id
        Long loginUserID = UserHolder.getUserId();
        //构建comment
        //2.构建Comment对象
        Comment comment = new Comment();
        comment.setCommentType(3);//1：点赞
        comment.setTargetId(new ObjectId(publishId)); //动态id
        comment.setUserId(loginUserID);//点赞的人
        comment.setTargetType(1); //1 对动态的操作, 这个条件可以省略 targetId就是唯一

        long loveCount = commentApi.remove(comment);

        String key = "publish_love_" + loginUserID + "_" + publishId;
        // 删除redis对点赞的标记
        redisTemplate.delete(key);
        return loveCount;
    }

    /**
     * 分页查询某个动态的评论列表
     *
     * @param publishId
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult<CommentVo> findPage(String publishId, Long page, Long pageSize) {

        //1. 调用api通过动态id分页查询评论列表
        PageResult result = commentApi.findPage(publishId, page, pageSize);

        //2. 获取分页的结果集
        List<Comment> commentList = result.getItems();
        List<CommentVo> voList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(commentList)) {

            //3. 获取所有评论者的id
            List<Long> UserListID = commentList.stream().map(Comment::getUserId).collect(Collectors.toList());

            //4. 批量查询评论者详情
            List<UserInfo> userInfoList = userInfoApi.findByBatchId(UserListID);

            //5. 评论者详情转成map
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, u -> u));

            //6. 构建vo，转成vo
            voList = commentList.stream().map(Comment -> {
                CommentVo vo = new CommentVo();

                // 复制评论内容
                BeanUtils.copyProperties(Comment, vo);
                vo.setId(Comment.getId().toHexString());
                vo.setCreateDate(RelativeDateFormat.format(new Date(Comment.getCreated())));
                // 复制用户详情
                UserInfo userInfo = userInfoMap.get(Comment.getUserId());
                BeanUtils.copyProperties(userInfo, vo);
                String key = "comment_like_" + UserHolder.getUserId() + "_" + vo.getId();
                if (redisTemplate.hasKey(key)) {
                    // 点赞过了
                    vo.setHasLiked(1);
                }
                return vo;
            }).collect(Collectors.toList());

        }
        result.setItems(voList);
        //7. 返回
        return result;

    }

    /**
     * 发表评论
     *
     * @param paramMap
     */
    public void add(Map<String, String> paramMap) {

        //1. 动态id
        String publishId = paramMap.get("movementId");
        //2. 评论内容
        String content = paramMap.get("comment");
        //3. 构建评论对象
        Comment comment = new Comment();
        comment.setCommentType(2);
        comment.setTargetType(1);
        comment.setContent(content);
        comment.setUserId(UserHolder.getUserId()); //评论者是登陆用户
        comment.setTargetId(new ObjectId(publishId)); // 动态id
        //4. 调用api添加
        commentApi.save(comment);
    }

    /**
     * 对评论点赞
     *
     * @param commentId
     * @return
     */
    public long likeComment(String commentId) {
        //获取登录用户id
        Long loginUserID = UserHolder.getUserId();
        Comment comment = new Comment();
        //构建comment
        comment.setTargetId(new ObjectId(commentId)); //动态id
        comment.setUserId(loginUserID); // 点赞的人
        comment.setCommentType(1); //操作类型--点赞
        comment.setTargetType(3); //对评论操作
        //加入数据库
        long count = commentApi.likeComment(comment);
        //用redis标记这个用户已经对这个评论点赞了
        String key = "comment_like_" + loginUserID + "_" + commentId;

        redisTemplate.opsForValue().set(key, 1);

        return 0;
    }

    /**
     * 对评论取消点赞
     *
     * @param commentId
     * @return
     */
    public long dislikeComment(String commentId) {
        //构建评论对象
        Comment comment = new Comment();
        comment.setTargetId(new ObjectId(commentId)); //目标动态
        comment.setUserId(UserHolder.getUserId()); //登陆用户取消的点赞
        comment.setCommentType(1); //点赞、
        comment.setTargetType(3); //评论
        //调用api删除
        long count = commentApi.dislikeComment(comment);
        //删除redis中的key
        String key = "comment_like_" + UserHolder.getUserId() + "_" + commentId;
        redisTemplate.delete(key);
        return count;
    }
}

